<template>
  <div class="plant-ai-container">
    <div class="header-banner">
      <div class="banner-content">
        <h2>智能植物AI助手</h2>
        <p>您可以询问任何关于植物的问题，我将尽力提供专业的解答。</p>
      </div>
    </div>

    <!-- 聊天界面 -->
    <div class="chat-container">
      <!-- 左侧示例问题 -->
      <div class="example-questions">
        <h3>你可以这样问我</h3>
        <div class="question-list">
          <div
            class="question-item"
            v-for="(question, index) in exampleQuestions"
            :key="index"
            @click="askExample(question)"
          >
            <el-icon><ChatLineRound /></el-icon>
            <span>{{ question }}</span>
          </div>
        </div>

        <!-- 模型选择器 -->
        <div class="model-selector">
          <h3>选择AI模型</h3>
          <el-select
            v-model="selectedModel"
            placeholder="选择模型"
            @change="onModelChange"
          >
            <el-option
              v-for="model in aiModels"
              :key="model.id"
              :label="model.name"
              :value="model.id"
            >
              <div class="model-option">
                <span>{{ model.name }}</span>
                <small>{{ model.description }}</small>
              </div>
            </el-option>
          </el-select>
        </div>
      </div>

      <!-- 右侧聊天界面 -->
      <div class="chat-main">
        <div class="messages" ref="messagesContainer">
          <!-- 欢迎消息 -->
          <div class="message system">
            <div class="message-content">
              <div v-html="welcomeMessage"></div>
            </div>
          </div>

          <!-- 消息列表 -->
          <div
            v-for="(message, index) in messages"
            :key="index"
            :class="['message', message.role]"
          >
            <div class="avatar">
              <el-avatar
                :icon="
                  message.role === 'user'
                    ? 'el-icon-user'
                    : 'el-icon-chat-dot-round'
                "
                :size="40"
                :src="message.role === 'user' ? userAvatar : botAvatar"
              ></el-avatar>
            </div>
            <div class="message-content">
              <div
                v-if="message.role === 'assistant'"
                v-html="renderMarkdown(message.content)"
                class="markdown-body"
              ></div>
              <div v-else>{{ message.content }}</div>
            </div>
          </div>

          <!-- 加载指示器 -->
          <div v-if="loading" class="message assistant loading">
            <div class="avatar">
              <el-avatar
                :icon="'el-icon-chat-dot-round'"
                :size="40"
                :src="botAvatar"
              ></el-avatar>
            </div>
            <div class="message-content">
              <div class="typing-indicator">
                <span></span>
                <span></span>
                <span></span>
              </div>
            </div>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="input-area">
          <el-input
            v-model="userInput"
            type="textarea"
            :rows="2"
            placeholder="请输入您的问题..."
            @keyup.enter.native="sendMessage"
            :disabled="loading"
          />
          <el-button
            type="primary"
            @click="sendMessage"
            :loading="loading"
            :disabled="!userInput.trim()"
          >
            发送
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, computed } from "vue";
import { ElMessage } from "element-plus";
import { ChatLineRound } from "@element-plus/icons-vue";
import zhipuAIApi from "@/api/ZhipuAIApi";
import MarkdownIt from "markdown-it";
import hljs from "highlight.js";
import "highlight.js/styles/github.css";

// 创建markdown渲染器
const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return (
          '<pre class="hljs"><code>' +
          hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
          "</code></pre>"
        );
      } catch (__) {}
    }
    return (
      '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + "</code></pre>"
    );
  },
});

// 定义状态变量
const userInput = ref("");
const messages = ref([]);
const loading = ref(false);
const messagesContainer = ref(null);
const aiModels = ref([]);
const selectedModel = ref("glm-4-flash");
const userAvatar = ref("@头像.png"); // 用户头像
// 机器人头像设置为base64编码的内联图片
const botAvatar = ref(
  ""
);

// 示例问题
const exampleQuestions = ref([
  "多肉植物如何正确浇水？",
  "常见植物病虫害的识别与防治",
  "如何提高植物繁殖成功率？",
  "室内植物的最佳光照条件是什么？",
  "请推荐几种适合初学者种植的植物",
]);

// 欢迎消息
const welcomeMessage = ref(`<div class="welcome">
  <h3>🌱 欢迎使用智能植物AI助手!</h3>
  <p>加载中...</p>
</div>`);

// 获取模型名称
function getModelName(modelId) {
  const model = aiModels.value.find((m) => m.id === modelId);
  return model ? model.name : modelId;
}

// 渲染Markdown
function renderMarkdown(text) {
  if (!text) return "";

  // 高亮植物名称
  const highlightedText = highlightPlantNames(text);
  return md.render(highlightedText);
}

// 高亮植物名称
function highlightPlantNames(text) {
  // 植物名称正则表达式 - 这里可以根据实际情况调整
  const plantNameRegex =
    /(?:[\u4e00-\u9fa5]{1,2}科)?[\u4e00-\u9fa5]{1,10}(?:草|树|花|兰|茶|莓|果|竹|松|藤|蕨|葵|荷|芦|菊|菇|蘑菇|仙人掌|多肉)?/g;

  return text.replace(plantNameRegex, (match) => {
    // 避免替换太短或太通用的词
    if (
      match.length < 2 ||
      /^(这个|那个|什么|如何|可以|应该|一个|我们|您好|谢谢)$/.test(match)
    ) {
      return match;
    }
    return `<span class="plant-name">${match}</span>`;
  });
}

// 更改模型
function onModelChange(value) {
  ElMessage.success(`已切换至${getModelName(value)}模型`);
}

// 发送示例问题
function askExample(question) {
  userInput.value = question;
  sendMessage();
}

// 发送消息
async function sendMessage() {
  if (!userInput.value.trim() || loading.value) return;

  // 添加用户消息
  const userMessage = userInput.value.trim();
  messages.value.push({ role: "user", content: userMessage });
  userInput.value = "";

  // 滚动到底部
  await nextTick();
  scrollToBottom();

  loading.value = true;

  try {
    // 使用安全模式API调用后端
    const response = await zhipuAIApi.safeChatWithAI(
      userMessage,
      selectedModel.value
    );

    // 添加AI回复
    messages.value.push({ role: "assistant", content: response });

    // 滚动到底部
    await nextTick();
    scrollToBottom();
  } catch (error) {
    console.error("AI回复失败", error);
    ElMessage.error("获取AI回复失败，请稍后再试");

    // 添加错误消息
    messages.value.push({
      role: "assistant",
      content:
        "抱歉，我暂时无法回答您的问题。可能是由于网络原因或服务器繁忙，请稍后再试。",
    });
  } finally {
    loading.value = false;
  }
}

// 滚动到底部
function scrollToBottom() {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
  }
}

// 加载模型列表
async function loadModels() {
  try {
    const models = await zhipuAIApi.getAIModels();
    aiModels.value = models;
  } catch (error) {
    console.error("获取模型列表失败", error);
    // 使用默认模型列表
    aiModels.value = [
      {
        id: "glm-4-flash",
        name: "智谱GLM-4-flash",
        description: "更快的响应速度，适合一般对话场景",
      },
      {
        id: "glm-4",
        name: "智谱GLM-4",
        description: "最强大的模型，适合复杂推理和创作",
      },
      {
        id: "glm-3-turbo",
        name: "智谱GLM-3-turbo",
        description: "经济实惠的选择，适合一般任务",
      },
    ];
  }
}

// 组件挂载时加载模型列表和欢迎消息
onMounted(async () => {
  // 加载模型列表
  loadModels();

  // 加载欢迎消息
  try {
    const welcomeText = await zhipuAIApi.getWelcomeMessage();
    welcomeMessage.value = `<div class="welcome">
      ${renderMarkdown(welcomeText)}
      <p>当前使用模型: <strong>${getModelName(selectedModel.value)}</strong></p>
    </div>`;
  } catch (error) {
    console.error("获取欢迎消息失败", error);
    // 保持默认欢迎消息
    welcomeMessage.value = `<div class="welcome">
      <h3>🌱 欢迎使用智能植物AI助手!</h3>
      <p>我可以回答关于植物种植、养护、病虫害防治等各方面的问题。</p>
      <p>当前使用模型: <strong>${getModelName(selectedModel.value)}</strong></p>
    </div>`;
  }
});
</script>

<style scoped>
.plant-ai-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 200px);
  background-color: #f9f9f9;
  border-radius: 8px;
  overflow: hidden;
}

.header-banner {
  background: linear-gradient(135deg, #4caf50, #2e7d32);
  color: white;
  padding: 20px;
  text-align: center;
  position: relative;
  overflow: hidden;
}

.header-banner::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cpath fill='%23ffffff' fill-opacity='0.05' d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z'/%3E%3C/svg%3E");
  opacity: 0.7;
  z-index: 0;
}

.banner-content {
  position: relative;
  z-index: 1;
}

.banner-content h2 {
  margin: 0;
  font-size: 24px;
}

.banner-content p {
  margin: 8px 0 0;
  font-size: 14px;
  opacity: 0.9;
}

.chat-container {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.example-questions {
  width: 280px;
  padding: 20px;
  background-color: #f0f7f0;
  border-right: 1px solid #e0e0e0;
  overflow-y: auto;
}

.example-questions h3 {
  margin-top: 0;
  color: #2e7d32;
  font-size: 16px;
}

.question-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.question-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  background-color: white;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
}

.question-item:hover {
  background-color: #eaf7ea;
  border-color: #4caf50;
}

.model-selector {
  margin-top: 20px;
}

.model-option {
  display: flex;
  flex-direction: column;
}

.model-option small {
  color: #666;
  font-size: 12px;
}

.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: white;
}

.messages {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.message {
  display: flex;
  gap: 12px;
  max-width: 80%;
}

.message.user {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.message.assistant,
.message.system {
  align-self: flex-start;
}

.message.system .message-content {
  background-color: #f0f7f0;
  border: 1px dashed #4caf50;
}

.avatar {
  flex-shrink: 0;
}

.message-content {
  padding: 12px 16px;
  border-radius: 16px;
  background-color: #f5f5f5;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.message.user .message-content {
  background-color: #e3f2fd;
  color: #0d47a1;
  border-top-right-radius: 4px;
}

.message.assistant .message-content {
  background-color: #f1f8e9;
  color: #33691e;
  border-top-left-radius: 4px;
}

.input-area {
  display: flex;
  gap: 10px;
  padding: 16px;
  border-top: 1px solid #c8e6c9;
  background-color: #f8fdf8;
}

.input-area .el-input {
  flex: 1;
}

.input-area .el-button {
  background-color: #4caf50;
  border-color: #388e3c;
  transition: all 0.3s;
}

.input-area .el-button:hover:not(:disabled) {
  background-color: #388e3c;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* 加载指示器 */
.typing-indicator {
  display: flex;
  gap: 4px;
}

.typing-indicator span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #4caf50;
  animation: typing 1.4s infinite both;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0% {
    opacity: 0.3;
    transform: translateY(0);
  }
  25% {
    opacity: 1;
    transform: translateY(-3px);
  }
  50% {
    opacity: 0.3;
    transform: translateY(0);
  }
  100% {
    opacity: 0.3;
    transform: translateY(0);
  }
}

/* 植物名称高亮 */
:deep(.plant-name) {
  color: #2e7d32;
  font-weight: bold;
  text-decoration: underline;
  text-decoration-color: rgba(76, 175, 80, 0.3);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}

/* Markdown样式 */
:deep(.markdown-body) {
  font-family: inherit;
}

:deep(.markdown-body pre) {
  background-color: #f6f8fa;
  border-radius: 6px;
  padding: 16px;
  overflow: auto;
}

:deep(.markdown-body code) {
  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
  font-size: 85%;
}

:deep(.markdown-body p) {
  margin-top: 0;
  margin-bottom: 10px;
}

:deep(.markdown-body ul),
:deep(.markdown-body ol) {
  padding-left: 2em;
}

:deep(.markdown-body table) {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 16px;
}

:deep(.markdown-body table th),
:deep(.markdown-body table td) {
  border: 1px solid #dfe2e5;
  padding: 6px 13px;
}

:deep(.markdown-body table tr:nth-child(2n)) {
  background-color: #f6f8fa;
}

.welcome {
  line-height: 1.5;
}

/* 头像样式增强 */
.avatar .el-avatar {
  border: 2px solid #4caf50;
  box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
  overflow: hidden;
  transition: all 0.3s;
}

/* AI头像特殊样式 */
.message.assistant .avatar .el-avatar {
  background-color: #e8f5e9;
  transform: scale(1.05);
}

/* 用户头像特殊样式 */
.message.user .avatar .el-avatar {
  background-color: #e3f2fd;
}

/* 鼠标悬停效果 */
.avatar .el-avatar:hover {
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}

/* 更美观的消息内容 */
.message-content {
  border-radius: 16px;
  transition: all 0.3s;
}

.message.user .message-content {
  border-top-right-radius: 4px;
}

.message.assistant .message-content {
  border-top-left-radius: 4px;
}

/* 输入区域美化 */
.input-area {
  background-color: #f8fdf8;
  border-top: 1px solid #c8e6c9;
}

.input-area .el-button {
  background-color: #4caf50;
  border-color: #388e3c;
  transition: all 0.3s;
}

.input-area .el-button:hover:not(:disabled) {
  background-color: #388e3c;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
</style> 